#ifndef _TASKQUEUE_H
#define _TASKQUEUE_H

#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;
using std::function;
using std::queue;
using std::mutex;
using std::unique_lock;
using std::lock_guard;
using std::condition_variable;

using ElemType = function<void()>;  // 任务队列所存储的数据类型

extern mutex coutMutex;  // 只声明，不定义；
                         // 用于消费者/生产者 互斥进行打印操作
                         // 若直接将全局变量定义在头文件中，会导致当多个源文件都使用该头文件时，造成重定义问题


class TaskQueue {
public: 
    
    /**
     * @param capa
     */
    TaskQueue(size_t capa);
        
    ~TaskQueue();
        
    /**
     * @param val
     */
    void push(ElemType && val);  // 使用右值！！
        
    ElemType pop();
        
    bool full();
        
    bool empty();
        
    void wakeup(); // 唤醒所有子线程
    
private: 
    size_t _capacity;
    queue<ElemType> _que;
    mutex _mtx;
    condition_variable _condi;  // 所有线程都可以阻塞到同一个条件变量上
    bool _isExit;  // _flag
};

#endif //_TASKQUEUE_H